package com.xiaoyu.lanling.feature.util.mixdata

import `in`.srain.cube.cache.DiskFileUtils
import `in`.srain.cube.concurrent.AppThreads
import `in`.srain.cube.diskcache.FileUtils
import `in`.srain.cube.util.CLog
import `in`.srain.cube.util.StringUtil
import `in`.srain.cube.util.ZipUtil
import `in`.srain.cube.util.internal.AppObserver
import android.text.TextUtils
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.data.UserData
import com.xiaoyu.base.utils.ListUtil
import com.xiaoyu.base.utils.upload.UploadImageOriginalType
import com.xiaoyu.base.utils.upload.UploadMediaType
import com.xiaoyu.base.utils.upload.UploadParam
import com.xiaoyu.lanling.util.upload.UploadCategory
import com.xiaoyu.lib_av.manager.CallManager
import java.io.File
import java.io.IOException
import java.util.*

class MixDataUploader private constructor() {

    fun submit(jobId: String) {
        AppThreads.runOnIOThread(Task(jobId))
    }

    private inner class Task constructor(private val jobId: String) : Runnable {

        private val copyDestParentDir: File = File(sZipsDir, jobId)
        private val zipDestFile: File = File(sZipsDir, "${UserData.getInstance().uid}-$jobId.zip")

        override fun run() {
            if (!copyDestParentDir.mkdir()) {
                return
            }
            copy(sUploadSrcFiles, copyDestParentDir)
            if (copyDestParentDir.list().isEmpty()) {
                return
            }
            zip(copyDestParentDir, zipDestFile)
            if (zipDestFile.length() <= 0) {
                return
            }
            val url = upload(zipDestFile)
            if (TextUtils.isEmpty(url)) {
                return
            }
            notifyUploaded(jobId, url)
        }

        private fun copy(srcFiles: List<File?>, destParentDir: File) {
            var srcFiles: List<File?>? = srcFiles
            srcFiles = ListUtil.filterList(srcFiles) { obj: File? -> obj!!.exists() }
            ListUtil.forEach(srcFiles, AppObserver<File> { srcFile: File -> copySingle(srcFile, destParentDir) })
        }

        private fun copySingle(srcFile: File, destParentDir: File) {
            val destFile = File(destParentDir, srcFile.name)
            try {
                if (srcFile.isDirectory) {
                    if (destFile.mkdir()) {
                        copy(listOf(*srcFile.listFiles()), destFile)
                    }
                } else {
                    if (destFile.createNewFile()) {
                        FileUtils.copy(srcFile, destFile)
                    }
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }

        private fun zip(src: File, dest: File) {
            ZipUtil.zipFile(src, dest)
            src.delete()
        }

        private fun upload(file: File): String {
            return try {
                UploadParam(file.absolutePath, UploadCategory.MIX_DATA, UploadMediaType.MIX, "", UploadImageOriginalType.ORIGINAL).uploadSync()
            } catch (e: Exception) {
                e.printStackTrace()
                StringUtil.blank()
            } finally {
                file.delete()
            }
        }

        private fun notifyUploaded(jobId: String, url: String) {
            CLog.i(TAG, "jobId=%s, url=%s", jobId, url)
            // final JsonEventRequest request = new JsonEventRequest(new Object(), NoReceiverJsonEvent.class);
            // final RequestData requestData = request.getRequestData();
            // requestData.setRequestUrl(HttpConfig.UTIL_NOTIFY_MIX_DATA_UPLOADED);
            // requestData.addQueryData("id", jobId);
            // requestData.addQueryData("url", url);
            // request.enqueue();
        }
    }

    companion object {
        private val TAG = MixDataUploader::class.java.simpleName
        private const val ZIPS_DIR_NAME = "mix_data_zips"
        private const val FILE_CACHE_SIZE_IN_KB = 40 * 1024 // 40M;
        val instance = MixDataUploader()
        private val sZipsDir = createZipsDir()
        private val sUploadSrcFiles = createUploadSrcFiles()

        private fun createZipsDir(): File {
            val info: DiskFileUtils.CacheDirInfo = DiskFileUtils.getDiskCacheDir(AppContext.getContext(), ZIPS_DIR_NAME, FILE_CACHE_SIZE_IN_KB.toLong())
            val zipsDir: File = info.path
            if (!zipsDir.exists()) {
                zipsDir.mkdirs()
            }
            return zipsDir
        }

        private fun createUploadSrcFiles(): List<File?> {
            val files: MutableList<File?> = LinkedList()
            // files.add(new File(FileNameUtil.combine(NIMClient.getSdkStorageDirPath(), "log", "nim_sdk.log")));
            // files.add(new File(AppDatabase.getCurrentDatabase().getOpenHelper().getReadableDatabase().getPath()));
            // files.add(new File(GlobalDatabase.getCurrentDatabase().getOpenHelper().getReadableDatabase().getPath()));
            files.add(CallManager.instance.logDir)
            return files
        }
    }
}